#include <iostream>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/multi_point.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/boost_tuple.hpp>

namespace bg = boost::geometry;
namespace bgm = bg::model;
BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)

typedef boost::tuple<double, double> point;
typedef bgm::d2::point_xy<double> point_xy;

typedef bgm::multi_point<point_xy> points;

typedef bgm::polygon<point_xy> hull_point;
typedef bgm::polygon<point_xy> polygon;

using namespace std;

/**
 * @brief 将point数组转为内部使用的格式
 * 
 * @param p point array
 * @return points 
 */
points convert(vector<point> p)
{
    points res;
    for (auto i = p.begin(); i != p.end(); i++)
    {
        res.push_back(point_xy(i->head, i->tail.head));
    }
    return res;
}

/**
 * @brief Get the Hull Points object, 求出顺时针的凸包
 * 
 * @param p 任意顺序的四个点
 * @return bgm::polygon<point> 
 */
hull_point getHullPoints(points &p)
{
    bgm::polygon<point_xy> hull;
    bg::convex_hull(p, hull);
    return hull;
}

/**
 * @brief Get the Intersection Area object
 * 
 * @param rect1 第一个长方形
 * @param rect2 第二个长方形
 * @return double 
 */
double getIntersectionArea(polygon rect1, polygon rect2)
{
    std::deque<polygon> output;
    bg::intersection(rect1, rect2, output);
    auto polygon_output = output.begin();
    return bg::area(*polygon_output);
}

int main(int argc, char const *argv[])
{
    points rect1 = convert({{-1, 0}, {1, 1}, {1, 0}, {-1, 1}});
    points rect2 = convert({{0, 0}, {1, 1}, {0, 2}, {-1, 1}});

    auto hull1 = getHullPoints(rect1);
    auto hull2 = getHullPoints(rect2);

    auto res = getIntersectionArea(hull1, hull2);
    cout << res << endl;
    return 0;
}
